home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / internet / other / ka9q / ka9q_src.arc / NRCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-07-28  |  12.5 KB  |  590 lines

  1. /* net/rom user command processing */
  2.  
  3. #include <stdio.h>
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "ax25.h"
  7. #include "netrom.h"
  8. #include "timer.h"
  9. #include "iface.h"
  10. #include "lapb.h"
  11. #include "cmdparse.h"
  12. /*#include <ctype.h>*/
  13.  
  14. static int dointerface(), dobcnodes(), donodetimer(), donrroute(),
  15.            doobsotimer(), donodefilter() ;
  16.  
  17. static struct cmds nrcmds[] = {
  18.     "bcnodes",    dobcnodes,    2,    "netrom bcnodes <interface>", NULLCHAR,
  19.     "interface",    dointerface,    4,
  20.         "netrom interface <interface> <alias> <quality>",    NULLCHAR,
  21.     "nodefilter",    donodefilter,    0,    NULLCHAR,    NULLCHAR,
  22.     "nodetimer",    donodetimer,    0,    NULLCHAR,    NULLCHAR,
  23.     "obsotimer",    doobsotimer,    0,    NULLCHAR,    NULLCHAR,
  24.     "route",    donrroute,    0,    NULLCHAR,    NULLCHAR,
  25.     NULLCHAR,    NULLFP,        0,
  26.     "netrom subcommands: bcnodes interface nodetimer nodefilter obsotimer route",
  27.     NULLCHAR
  28. } ;
  29.  
  30. static struct timer nodetimer ;    /* timer for nodes broadcasts */
  31. static struct timer obsotimer ;    /* timer for aging routes */
  32.  
  33. /* Command multiplexer */
  34. donetrom(argc,argv)
  35. int argc ;
  36. char *argv[] ;
  37. {
  38.     return subcmd(nrcmds,argc,argv) ;
  39. }
  40.  
  41. static int dorouteadd(), doroutedrop(), doroutedump(), dorouteinfo() ;
  42.  
  43. static struct cmds routecmds[] = {
  44.     "add",    dorouteadd,    6,
  45.         "netrom route add <alias> <destination> <interface> <quality> <neighbor>",
  46.         "add failed",
  47.     "drop",    doroutedrop, 4,
  48.         "netrom route drop <destination> <neighbor> <interface>",
  49.         "drop failed",
  50.     "info", dorouteinfo, 2,
  51.         "netrom route info <destination>", NULLCHAR,
  52.     NULLCHAR,    NULLFP,    0,
  53.         "netrom route subcommands: add drop info",
  54.         NULLCHAR
  55. } ;
  56.  
  57. /* Route command multiplexer */
  58. static
  59. donrroute(argc, argv)
  60. int argc ;
  61. char *argv[] ;
  62. {
  63.     if (argc < 2) {
  64.         doroutedump() ;
  65.         return 0 ;
  66.     }
  67.     return subcmd(routecmds,argc,argv) ;
  68. }
  69.  
  70. /* Dump a list of known routes */
  71. static
  72. doroutedump()
  73. {
  74.     register struct nrroute_tab *rp ;
  75.     register int i, column ;
  76.     char buf[16] ;
  77.     char *cp ;
  78.     
  79.     column = 1 ;
  80.     
  81.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  82.         for (rp = nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rp->next) {
  83.             strcpy(buf,rp->alias) ;
  84.             /* remove trailing spaces */
  85.             if ((cp = index(buf,' ')) == NULLCHAR)
  86.                 cp = &buf[strlen(buf)] ;
  87.             if (cp != buf)        /* don't include colon for null alias */
  88.                 *cp++ = ':' ;
  89.             pax25(cp,&rp->call) ;
  90.             printf("%-16s  ",buf) ;
  91.             if (column++ == 4) {
  92.                 printf("\n") ;
  93.                 column = 1 ;
  94.             }
  95.         }
  96.  
  97.     if (column != 1)
  98.         printf("\n") ;
  99.         
  100.     return 0 ;
  101. }
  102.  
  103. /* print detailed information on an individual route */
  104. dorouteinfo(argc,argv)
  105. int argc ;
  106. char *argv[] ;
  107. {
  108.     register struct nrroute_tab *rp ;
  109.     register struct nr_bind *bp ;
  110.     register struct nrnbr_tab *np ;
  111.     struct ax25_addr dest ;
  112.     char neighbor[60] ;
  113.  
  114.     if (setcall(&dest,argv[1]) == -1) {
  115.         printf ("bad destination name\n") ;
  116.         return -1 ;
  117.     }
  118.         
  119.     if ((rp = find_nrroute(&dest)) == NULLNRRTAB) {
  120.         printf("no such route\n") ;
  121.         return -1 ;
  122.     }
  123.  
  124.     for (bp = rp->routes ; bp != NULLNRBIND ; bp = bp->next) {
  125.         np = bp->via ;
  126.         psax25(neighbor,np->call) ;
  127.         printf("%1s %3d  %3d  %-8s  %s\n",
  128.                 (bp->flags & NRB_PERMANENT ? "P" : " "),
  129.                 bp->quality,bp->obsocnt,
  130.                 nrifaces[np->interface].interface->name,
  131.                 neighbor) ;
  132.     }
  133.     return 0 ;
  134. }
  135.         
  136. /* convert a null-terminated alias name to a blank-filled, upcased */
  137. /* version.  Return -1 on failure. */
  138. static int
  139. putalias(to,from)
  140. register char *to, *from ;
  141. {
  142.     int len, i ;
  143.     
  144.     if ((len = strlen(from)) > ALEN) {
  145.         printf ("alias too long - six characters max\n") ;
  146.         return -1 ;
  147.     }
  148.     
  149.     for (i = 0 ; i < ALEN ; i++) {
  150.         if (i < len) {
  151.             if (islower(*from))
  152.                 *to++ = toupper(*from++) ;
  153.             else
  154.                 *to++ = *from++ ;
  155.         }
  156.         else
  157.             *to++ = ' ' ;
  158.     }
  159.             
  160.     *to = '\0' ;
  161.     return 0 ;
  162. }
  163.  
  164. /* Add a route */
  165. dorouteadd(argc, argv)
  166. int argc ;
  167. char *argv[] ;
  168. {
  169.     char alias[7] ;
  170.     struct ax25_addr dest ;
  171.     unsigned quality ;
  172.     char neighbor[AXALEN * 3] ;
  173.     register int i ;
  174.     int naddr ;
  175.  
  176.     /* format alias (putalias prints error message if necessary) */
  177.     if (putalias(alias,argv[1]) == -1)
  178.         return -1 ;
  179.  
  180.     /* format destination callsign */
  181.     if (setcall(&dest,argv[2]) == -1) {
  182.         printf("bad destination callsign\n") ;
  183.         return -1 ;
  184.     }
  185.  
  186.     /* find interface */
  187.     for (i = 0 ; i < nr_numiface ; i++)
  188.         if (!strcmp(nrifaces[i].interface->name,argv[3]))
  189.             break ;
  190.     if (i == nr_numiface) {
  191.         printf("Interface \"%s\" not found\n",argv[3]) ;
  192.         return -1 ;
  193.     }
  194.     
  195.     /* get and check quality value */
  196.     if ((quality = atoi(argv[4])) > 255) {
  197.         printf("maximum route quality is 255\n") ;
  198.         return -1 ;
  199.     }
  200.  
  201.     /* make sure no more than 2 digis */
  202.     naddr = argc - 5 ;
  203.     if (naddr > 3) {
  204.         printf("no more than 2 digipeaters for a net/rom neighbor\n") ;
  205.         return -1 ;
  206.     }
  207.     
  208.     /* format neighbor address string */
  209.     setpath(neighbor,&argv[5],naddr) ;
  210.  
  211.     return nr_routeadd(alias,&dest,i,quality,neighbor,1) ;
  212. }
  213.  
  214.  
  215. /* drop a route */
  216. static
  217. doroutedrop(argc,argv)
  218. int argc ;
  219. char *argv[] ;
  220. {
  221.     struct ax25_addr dest, neighbor ;
  222.     register int i ;
  223.  
  224.     /* format destination and neighbor callsigns */
  225.     if (setcall(&dest,argv[1]) == -1) {
  226.         printf("bad destination callsign\n") ;
  227.         return -1 ;
  228.     }
  229.     if (setcall(&neighbor,argv[2]) == -1) {
  230.         printf("bad neighbor callsign\n") ;
  231.         return -1 ;
  232.     }
  233.  
  234.     /* find interface */
  235.     for (i = 0 ; i < nr_numiface ; i++)
  236.         if (!strcmp(nrifaces[i].interface->name,argv[3]))
  237.             break ;
  238.     if (i == nr_numiface) {
  239.         printf("Interface \"%s\" not found\n",argv[3]) ;
  240.         return -1 ;
  241.     }
  242.  
  243.     return nr_routedrop(&dest,&neighbor,i) ;
  244. }
  245.     
  246.     
  247. /* make an interface available to net/rom */
  248. int
  249. dointerface(argc,argv)
  250. int argc ;
  251. char *argv[] ;
  252. {
  253.     register char *sp, *dp ;
  254.     int i, len ;
  255.     register struct interface *ifp ;
  256.     extern struct interface *ifaces ;
  257.  
  258.     if (nr_interface == NULLIF) {
  259.         printf("Attach netrom interface first\n") ;
  260.         return 1 ;
  261.     }
  262.     
  263.     if (nr_numiface >= NRNUMIFACE) {
  264.         printf("Only %d net/rom interfaces available\n",NRNUMIFACE) ;
  265.         return 1 ;
  266.     }
  267.     
  268.     for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  269.         if(strcmp(argv[1],ifp->name) == 0)
  270.             break;
  271.     }
  272.     if(ifp == NULLIF){
  273.         printf("Interface \"%s\" unknown\n",argv[1]);
  274.         return 1;
  275.     }
  276.     if (!(ifp->flags != CONNECT_MODE)) {    /* DG2KK: was: IF_AX25 */
  277.         printf("Must be an ax.25 interface\n") ;
  278.         return 1 ;
  279.     }
  280.     for (i = 0 ; i < nr_numiface ; i++)
  281.         if (nrifaces[i].interface == ifp) {
  282.             printf("Interface \"%s\" is already registered\n",argv[1]) ;
  283.             return 1 ;
  284.         }
  285.         
  286.     nrifaces[nr_numiface].interface = ifp ;
  287.  
  288.     if (putalias(nrifaces[nr_numiface].alias,argv[2]) == -1)
  289.         return 1 ;
  290.         
  291.     if ((nrifaces[nr_numiface].quality = atoi(argv[3])) > 255) {
  292.         printf("Quality cannot be greater than 255\n") ;
  293.         return 1 ;
  294.     }
  295.         
  296.     nr_numiface++ ;            /* accept this interface */
  297.     return 0 ;
  298. }
  299.  
  300. /* Broadcast nodes list on named interface. */
  301.  
  302. int
  303. dobcnodes(argc,argv)
  304. int argc ;
  305. char *argv[] ;
  306. {
  307.     register int i ;
  308.     for (i = 0 ; i < nr_numiface ; i++)
  309.         if (!strcmp(nrifaces[i].interface->name,argv[1]))
  310.             break ;
  311.     if (i == nr_numiface) {
  312.         printf("Interface \"%s\" not found\n",argv[1]) ;
  313.         return 1 ;
  314.     }
  315.         
  316.     nr_bcnodes(i) ;
  317. }
  318.  
  319. #define TICKSPERSEC    (1000 / MSPTICK)    /* Ticks per second */
  320.  
  321. /* Set outbound node broadcast interval */
  322. static int
  323. donodetimer(argc,argv)
  324. int argc;
  325. char *argv[];
  326. {
  327.     int donodetick();
  328.  
  329.     if(argc < 2){
  330.         printf("%d/%d\n",(nodetimer.start - nodetimer.count)/TICKSPERSEC,
  331.         nodetimer.start/TICKSPERSEC);
  332.         return 0;
  333.     }
  334.     stop_timer(&nodetimer) ;    /* in case it's already running */
  335.     nodetimer.func = (void (*)())donodetick;/* what to call on timeout */
  336.     nodetimer.arg = NULLCHAR;        /* dummy value */
  337.     nodetimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  338.     start_timer(&nodetimer);        /* and fire it up */
  339.     return 0;
  340. }
  341.  
  342. static int
  343. donodetick()
  344. {
  345.     register int i ;
  346.  
  347.     for (i = 0 ; i < nr_numiface ; i++)
  348.         nr_bcnodes(i) ;
  349.  
  350.     /* Restart timer */
  351.     start_timer(&nodetimer) ;
  352. }
  353.  
  354. /* Set timer for aging routes */
  355. static int
  356. doobsotimer(argc,argv)
  357. int argc;
  358. char *argv[];
  359. {
  360.     extern int doobsotick();
  361.  
  362.     if(argc < 2){
  363.         printf("%d/%d\n",(obsotimer.start - obsotimer.count)/TICKSPERSEC,
  364.         obsotimer.start/TICKSPERSEC);
  365.         return 0;
  366.     }
  367.     stop_timer(&obsotimer) ;    /* just in case it's already running */
  368.     obsotimer.func = (void (*)())doobsotick;/* what to call on timeout */
  369.     obsotimer.arg = NULLCHAR;        /* dummy value */
  370.     obsotimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  371.     start_timer(&obsotimer);        /* and fire it up */
  372.     return 0;
  373. }
  374.  
  375.  
  376. /* Go through the routing table, reducing the obsolescence count of
  377.  * non-permanent routes, and purging them if the count reaches 0
  378.  */
  379. static int
  380. doobsotick()
  381. {
  382.     register struct nrnbr_tab *np ;
  383.     register struct nrroute_tab *rp, *rpnext ;
  384.     register struct nr_bind *bp, *bpnext ;
  385.     struct ax25_addr neighbor ;
  386.     int i ;
  387.  
  388.     for (i = 0 ; i < NRNUMCHAINS ; i++) {
  389.         for (rp = nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rpnext) {
  390.             rpnext = rp->next ;     /* save in case we free this route */
  391.             for (bp = rp->routes ; bp != NULLNRBIND ; bp = bpnext) {
  392.                 bpnext = bp->next ;    /* in case we free this binding */
  393.                 if (bp->flags & NRB_PERMANENT)    /* don't age these */
  394.                     continue ;
  395.                 if (--bp->obsocnt == 0) {        /* time's up! */
  396.                     if (bp->next != NULLNRBIND)
  397.                         bp->next->prev = bp->prev ;
  398.                     if (bp->prev != NULLNRBIND)
  399.                         bp->prev->next = bp->next ;
  400.                     else
  401.                         rp->routes = bp->next ;
  402.                     rp->num_routes-- ;            /* one less binding */
  403.                     np = bp->via ;                /* find the neighbor */
  404.                     free(bp) ;                    /* now we can free the bind */
  405.                     /* Check to see if we can free the neighbor */
  406.                     if (--np->refcnt == 0) {
  407.                         if (np->next != NULLNTAB)
  408.                             np->next->prev = np->prev ;
  409.                         if (np->prev != NULLNTAB)
  410.                             np->prev->next = np->next ;
  411.                         else {
  412.                             memcpy(neighbor.call,np->call,ALEN) ;
  413.                             neighbor.ssid = np->call[ALEN] ;
  414.                             nrnbr_tab[nrhash(&neighbor)] = np->next ;
  415.                         }
  416.                         free(np) ;    /* free the storage */
  417.                     }
  418.                 }
  419.             }
  420.             if (rp->num_routes == 0) {        /* did we free them all? */
  421.                 if (rp->next != NULLNRRTAB)
  422.                     rp->next->prev = rp->prev ;
  423.                 if (rp->prev != NULLNRRTAB)
  424.                     rp->prev->next = rp->next ;
  425.                 else
  426.                     nrroute_tab[i] = rp->next ;
  427.  
  428.                 free(rp) ;
  429.             }
  430.         }
  431.     }
  432.  
  433.     start_timer(&obsotimer) ;
  434. }
  435.  
  436.  
  437. static int donfadd(), donfdrop(), donfmode() ;
  438.  
  439. static struct cmds nfcmds[] = {
  440.     "add",    donfadd,    3,
  441.         "netrom nodefilter add <neighbor> <interface>",
  442.         "add failed",
  443.     "drop",    donfdrop,    3,
  444.         "netrom nodefilter drop <neighbor> <interface>",
  445.         "drop failed",
  446.     "mode",    donfmode,    0,    NULLCHAR,    NULLCHAR,
  447.     NULLCHAR,    NULLFP,    0,
  448.         "nodefilter subcommands: add drop mode",
  449.         NULLCHAR
  450. } ;
  451.  
  452. /* nodefilter command multiplexer */
  453. static
  454. donodefilter(argc,argv)
  455. int argc ;
  456. char *argv[] ;
  457. {
  458.     if (argc < 2) {
  459.         donfdump() ;
  460.         return 0 ;
  461.     }
  462.     return subcmd(nfcmds,argc,argv) ;
  463. }
  464.  
  465. /* display a list of <callsign,interface> pairs from the filter
  466.  * list.
  467.  */
  468. static
  469. donfdump()
  470. {
  471.     int i, column = 1 ;
  472.     struct nrnf_tab *fp ;
  473.     char buf[16] ;
  474.  
  475.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  476.         for (fp = nrnf_tab[i] ; fp != NULLNRNFTAB ; fp = fp->next) {
  477.             pax25(buf,&fp->neighbor) ;
  478.             printf("%-7s %-8s  ",
  479.                     buf,nrifaces[fp->interface].interface->name) ;
  480.             if (column++ == 4) {
  481.                 printf("\n") ;
  482.                 column = 1 ;
  483.             }
  484.         }
  485.  
  486.     if (column != 1)
  487.         printf("\n") ;
  488.  
  489.     return 0 ;
  490. }
  491.  
  492. /* add an entry to the filter table */
  493. static
  494. donfadd(argc,argv)
  495. int argc ;
  496. char *argv[] ;
  497. {
  498.     struct ax25_addr neighbor ;
  499.     register int i ;
  500.  
  501.     /* format callsign */
  502.     if (setcall(&neighbor,argv[1]) == -1) {
  503.         printf("bad neighbor callsign\n") ;
  504.         return -1 ;
  505.     }
  506.  
  507.     /* find interface */
  508.     for (i = 0 ; i < nr_numiface ; i++)
  509.         if (!strcmp(nrifaces[i].interface->name,argv[2]))
  510.             break ;
  511.     if (i == nr_numiface) {
  512.         printf("Interface \"%s\" not found\n",argv[2]) ;
  513.         return -1 ;
  514.     }
  515.  
  516.     return nr_nfadd(&neighbor,i) ;
  517. }
  518.  
  519. /* drop an entry from the filter table */
  520. static
  521. donfdrop(argc,argv)
  522. int argc ;
  523. char *argv[] ;
  524. {
  525.     struct ax25_addr neighbor ;
  526.     register int i ;
  527.  
  528.     /* format neighbor callsign */
  529.     if (setcall(&neighbor,argv[1]) == -1) {
  530.         printf("bad neighbor callsign\n") ;
  531.         return -1 ;
  532.     }
  533.  
  534.     /* find interface */
  535.     for (i = 0 ; i < nr_numiface ; i++)
  536.         if (!strcmp(nrifaces[i].interface->name,argv[2]))
  537.             break ;
  538.     if (i == nr_numiface) {
  539.         printf("Interface \"%s\" not found\n",argv[2]) ;
  540.         return -1 ;
  541.     }
  542.  
  543.     return nr_nfdrop(&neighbor,i) ;
  544. }
  545.  
  546. /* nodefilter mode subcommand */
  547. static
  548. donfmode(argc,argv)
  549. int argc ;
  550. char *argv[] ;
  551. {
  552.     if (argc < 2) {
  553.         printf("filter mode is ") ;
  554.         switch (nr_nfmode) {
  555.             case NRNF_NOFILTER:
  556.                 printf("none\n") ;
  557.                 break ;
  558.             case NRNF_ACCEPT:
  559.                 printf("accept\n") ;
  560.                 break ;
  561.             case NRNF_REJECT:
  562.                 printf("reject\n") ;
  563.                 break ;
  564.             default:
  565.                 printf("some strange, unknown value\n") ;
  566.         }
  567.         return 0 ;
  568.     }
  569.     
  570.     switch (argv[1][0]) {
  571.         case 'n':
  572.         case 'N':
  573.             nr_nfmode = NRNF_NOFILTER ;
  574.             break ;
  575.         case 'a':
  576.         case 'A':
  577.             nr_nfmode = NRNF_ACCEPT ;
  578.             break ;
  579.         case 'r':
  580.         case 'R':
  581.             nr_nfmode = NRNF_REJECT ;
  582.             break ;
  583.         default:
  584.             printf("modes are: none accept reject\n") ;
  585.             return -1 ;
  586.     }
  587.  
  588.     return 0 ;
  589. }
  590.